package nl.windgazer.facebook.components;

import java.util.ArrayList;
import java.util.Arrays;

import nl.windgazer.arachne.services.facebook.FacebookAPISettings;
import nl.windgazer.arachne.services.facebook.FacebookColorScheme;

import org.apache.tapestry5.BindingConstants;
import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.MarkupWriter;
import org.apache.tapestry5.annotations.AfterRenderTemplate;
import org.apache.tapestry5.annotations.BeforeRenderTemplate;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.annotations.SetupRender;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.ioc.annotations.Symbol;

public class XFBMLElement {

	//Injects and Persists

	@Inject
	private FacebookAPISettings _fb;

	@Inject
	private ComponentResources _cr;

	@Inject
	@Symbol(FacebookAPISettings.ENABLE_SERVICE)
	private boolean fbServiceEnabled;

	//Properties and Parameters

	private String id;

	@Parameter(required = false, principal = false, defaultPrefix = BindingConstants.PROP, name = "attribs")
	private String[] _attribs = new String[]{};

	@Parameter(required = false, principal = false, defaultPrefix = BindingConstants.LITERAL, name = "tag")
	private String _tag;

	//Here's some common properties that are shared by (most) XFBML elements

	/**
	 * Probably all of the social plugins support width setting
	 */
	@Parameter(required = false, principal = false, defaultPrefix = BindingConstants.LITERAL, name = "width")
	private String _width;

	/**
	 * Many of the 'larger' social plugins support this setting. Using it on a plugin that doesn't support it
	 * doesn't do any harm though.
	 */
	@Parameter(required = false, principal = false, defaultPrefix = BindingConstants.LITERAL, name = "height")
	private String _height;

	/**
	 * Any social plugin most certainly supports this option.
	 */
	@Parameter(required = false, principal = false, defaultPrefix = BindingConstants.LITERAL, name = "colorscheme")
	private FacebookColorScheme _colorscheme;

	/**
	 * Some social plugins support showing of faces (and then sometimes only in specific modes), this boolean
	 * can be used to hide them for those plugins that support faces.
	 */
	@Parameter(required = false, principal = false, defaultPrefix = BindingConstants.LITERAL, name = "show_faces")
	private boolean _showFaces = true;

	private boolean cancelRender;

	//Components

	//Events

	@SetupRender
	public boolean checkSkipRender() {
		return fbServiceEnabled;
	}

	public void setCancelRender(boolean cancelRender) {
		this.cancelRender = cancelRender;
	}

	@BeforeRenderTemplate
	void setupDefaultElementSettings() {
		id = _cr.getId();
		_fb.setRender(true);
	}

	@AfterRenderTemplate
	void renderXFBMLComment(MarkupWriter writer) {
		if (!cancelRender) {
			if (_tag != null) {
				writer.element("span", "id", id, "class", "xfbml");
				_fb.setXFBMLParse(id, _tag, getAttribs());
				writer.end();
			} else throw new RuntimeException("Cannot use this element without setting the tag parameter (which isn't set to required for improving extension options.");
		}
	}

	//Other (check for business-logic, it should not remain here)

	public String[] getAttribs() {
		final ArrayList<String> ats = new ArrayList<String>(Arrays.asList(_attribs));
		if (_width!=null) {
			ats.add("width");
			ats.add(_width);
		}
		if (_height!=null) {
			ats.add("height");
			ats.add(_height);
		}
		if (_colorscheme!=null) {
			ats.add("colorscheme");
			ats.add(_colorscheme.toString());
		}
		if (!_showFaces) {
			ats.add("show-faces");
			ats.add(String.valueOf(_showFaces));
		}
		return ats.toArray(new String[]{});
	}

	public void setAttribs(String ... attribs) {
		_attribs = attribs;
	}

	public void setTag(String tag) {
		_tag = tag;
	}

}
